package com.beta.service.impl;

import com.baomidou.framework.service.impl.SuperServiceImpl;
import com.baomidou.mybatisplus.plugins.Page;
import com.beta.constant.CommonConstant;
import com.beta.dto.admin.TransactionDetailDto;
import com.beta.dto.admin.TransactionDto;
import com.beta.em.transacrion.TransactionResource;
import com.beta.em.transacrion.TransactionSubject;
import com.beta.entity.*;
import com.beta.mapper.TransactionsMapper;
import com.beta.service.IDateTimeService;
import com.beta.service.IPaymentsService;
import com.beta.service.ITransactionsService;
import com.beta.service.IUsersService;
import com.beta.util.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
 *
 * Transactions 表数据服务层接口实现类
 *
 */
@Service
public class TransactionsService extends SuperServiceImpl<TransactionsMapper, Transactions> implements ITransactionsService {

    @Autowired
    private IPaymentsService paymentsService;
    @Autowired
    private IUsersService usersService;
    @Autowired
    private IDateTimeService dateTimeService;

    @Override
    public void createPayTransaction(String balanceCode, String accountCode, Orders order, Payments payment) {
        Transactions whereEntity = new Transactions().setBalanceCode(balanceCode);
        if (super.selectCount(whereEntity) > 0) {
            return ;
        }

        BigDecimal paymentFee = paymentsService.getPaymentFeeByOrderId(order.getId());
        Transactions transactions = new Transactions();
        Date dbDate = dateTimeService.toDbDate();
        transactions.setBalanceCode(balanceCode)
                .setCode(generateTransactionCode())
                .setBalanceAgency("易宝")
                .setResourceId(order.getId())
                .setResourceType(TransactionResource.ORDER.getValue())
                .setCityCode(order.getCityCode())
                .setCityName(order.getCityName())
                .setAmount(order.getAmount().subtract(paymentFee).setScale(2, CommonConstant.ROUNDING_MODE))
                .setUserId(order.getUserId())
                .setAccountCode(accountCode)
                .setSubject(TransactionSubject.PAYOUT.getValue())
                .setUpdatedAt(dbDate)
                .setCreatedAt(dbDate);
        insertSelective(transactions);
    }

    @Override
    public void createRefundTransaction(String balanceCode, Orders orders) {
        Date dbDate = dateTimeService.toDbDate();
        Transactions refundTransaction = new Transactions()
                .setCode(generateTransactionCode())
                .setBalanceCode(balanceCode)
                .setBalanceAgency("易宝")
                .setResourceId(orders.getId())
                .setResourceType(TransactionResource.ORDER.getValue())
                .setUserId(orders.getUserId())
                .setSubject(TransactionSubject.REFUND.getValue())
                .setCityName(orders.getCityName())
                .setCityCode(orders.getCityCode())
                .setUpdatedAt(dbDate)
                .setCreatedAt(dbDate);
        insertSelective(refundTransaction);
    }

    @Override
    public void createSettleTransaction(String balanceCode, OrderSettleQueues settleQueue, Orders orders) {
        Date dbDate = dateTimeService.toDbDate();
        Users users = usersService.selectOne(new Users().setLedgerCode(settleQueue.getLedgerCode()));
        Transactions refundTransaction = new Transactions()
                .setCode(generateTransactionCode())
                .setBalanceCode(balanceCode)
                .setBalanceAgency("易宝")
                .setResourceId(orders.getId())
                .setResourceType(TransactionResource.ORDER.getValue())
                .setUserId(users.getId())
                .setSubject(TransactionSubject.SETTLE.getValue())
                .setAccountCode(settleQueue.getLedgerCode())
                .setAmount(settleQueue.getAmount().abs())
                .setCityName(orders.getCityName())
                .setCityCode(orders.getCityCode())
                .setUpdatedAt(dbDate)
                .setCreatedAt(dbDate);
        insertSelective(refundTransaction);
    }

    private static String generateTransactionCode() {
        String yyMMddHHmmss = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));
        String rand7String = RandomUtils.randomStringWithLength(7);
        return yyMMddHHmmss + "0" + rand7String;
    }

    @Override
    public List<TransactionDto> getTransactions(Integer resourceId) {
        return baseMapper.getTransaction(resourceId);
    }


    @Override
    public Page<TransactionDto> getTransactions(Page<TransactionDto> page, String code, BigDecimal amountBegin, BigDecimal amountEnd,String username) {
        page.setRecords(baseMapper.getTransactions(page,code,amountBegin,amountEnd,username));
        return page;
    }

    @Override
    public TransactionDetailDto getTransactionDetail(Integer transactionId) {
        return baseMapper.getTransactionDetail(transactionId);
    }
}